﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms ;
//using MySQLDriverCS;
using MySql.Data.MySqlClient;
using System.Data;
using ShopfloorClass;
using SHOPFLOORFIELDS;
using System.IO;
using INJECTOR;
using System.Collections;

namespace TB100
{
    public struct setpoint
    {
        public double Setpoint;
        public double Uplimit;
        public double Lowelimit;
    }
    public enum eDriverType { DPS = 1, ATIC39, EEC_V, ATM_36 };

    public static class TB100FolderFunction
    {
        public static string GetCorrelationRootDir()
        {
            return "E:\\Documents\\CACC\\01 PESH\\Injector\\Testline\\Correlation\\SourceData\\2012\\";
        }

        public static string[] GetDirList(string rootDir)
        {
            string[] sTemp = new string[] { };
            sTemp = Directory.GetDirectories(rootDir);
            return sTemp;

        }


        public static string[] GetFileList(string sDirName)
        {
            string[] sTemp = new string[] { };

            sTemp = Directory.GetFiles(sDirName, "*.ttx", SearchOption.AllDirectories);
            return sTemp;
        }
    }

    public static class TB100Functions
    {
        public static  DataTable ConvertTB100GroupToDataTable(TB100Group TBGroup)
        {
            int i = 0;
            DataTable dt = new DataTable();
            dt.Columns.Add("id");
            dt.Columns.Add("Serial");
            dt.Columns.Add("Qd");
            dt.Columns.Add("Qd S%");
            dt.Columns.Add("Qs");
            dt.Columns.Add("Qs S%");
            foreach (Injector inj in TBGroup.Injectors)
            {
                i++;
                if (inj.Matrix  .Length < 3) continue;
                dt.Rows.Add(new string[] { 
                    i.ToString (),
                    inj.Matrix,
                    inj.Qd.ToString (),
                    inj.QdShift .ToString (),
                    inj.Qs.ToString (),
                    inj.QsShift.ToString ()
                });
            }
            return dt;
        }

        public static string TB100GroupToString(TB100Group myTB100Group)
        {
            string sTemp;
            string sSerial = "", sQd = "", sQdShift = "", sQs = "", sQsShift = "";

            foreach (Injector temp in myTB100Group.Injectors)
            {
                sSerial = sSerial + ',' + temp.Matrix;
                sQd = sQd + ',' + temp.Qd.ToString();
                sQdShift = sQdShift + ',' + temp.QdShift.ToString();
                sQs = sQs + ',' + temp.Qs.ToString();
                sQsShift = sQsShift + ',' + temp.QsShift.ToString();

            }
            sTemp = sSerial.Substring(1) + '|';
            sTemp = sTemp + sQd.Substring(1) + '|';
            sTemp = sTemp + sQdShift.Substring(1) + '|';
            sTemp = sTemp + sQs.Substring(1) + '|';
            sTemp = sTemp + sQsShift.Substring(1) + '|';
            return sTemp;
        }
        public static TableField_T040 FindFromTB_cr1T040(string matrix, string tablename)
        {
            int iFoundQty = 0;
            TableField_T040 res=new TableField_T040 ();
            MySqlCommand cmd = new MySqlCommand();
            DataTable dt = new DataTable();
            string sql;

            res.init();
            //ShopfloorClass.ShopfloorDB shopfloor = new ShopfloorClass.ShopfloorDB();
            sql = string.Format("select partid, offload, type_id, familycode, obj31, obj36, obj45, obj50, obj69, obj70, obj71, obj72, obj73, obj74 from {0} where partid = {1} orderby offload desc limit 1");
            dt = ShopfloorDB.Query(sql);
            iFoundQty = dt.Rows.Count;

            if (dt.Rows.Count < 1) return res;
            try
            {
                res.partid_ = dt.Rows[0][0].ToString();
                res.offload_ = Convert.ToInt64(dt.Rows[0][1].ToString());
                res.type_id_ = Convert.ToInt32(dt.Rows[0][2].ToString());
                res.familycode_ = Convert.ToInt32(dt.Rows[0][3].ToString());
                res.obj31_PRO_OP43_MD_FM_FLOW = Convert.ToDouble(dt.Rows[0][4].ToString());
                res.obj36_PRO_OP43_MS_FM_FLOW = Convert.ToDouble(dt.Rows[0][5].ToString());
                res.obj45_PRO_OP44_MD_BAL_FLOW = Convert.ToDouble(dt.Rows[0][6].ToString());
                res.obj50_PRO_OP44_MS_BAL_FLOW = Convert.ToDouble(dt.Rows[0][7].ToString());
                res.obj69_PRO_OP44_G_MD_BAL_MULT = Convert.ToDouble(dt.Rows[0][8].ToString());
                res.obj70_PRO_OP44_G_MS_BAL_MULT = Convert.ToDouble(dt.Rows[0][9].ToString());
                res.obj71_PRO_OP43_G_MD_FM_MULT = Convert.ToDouble(dt.Rows[0][10].ToString());
                res.obj72_PRO_OP43_G_MS_FM_MULT = Convert.ToDouble(dt.Rows[0][11].ToString());
                res.obj73_PRO_OP44_G_MD_BAL_MULT = Convert.ToDouble(dt.Rows[0][12].ToString());
                res.obj74_PRO_OP44_G_MS_BAL_MULT = Convert.ToDouble(dt.Rows[0][13].ToString());
            }
            catch (FormatException frmE)
            {
                System.IO.StreamWriter sw = new StreamWriter(System.Windows.Forms.Application.StartupPath.TrimEnd('\\') + "\\TB100Functions.log");
                sw.WriteLine(frmE.Message);
                sw.Close();
            }
            dt.Dispose();
            dt = null;
            return res;
        }

        //public TableField_T040 FindFromTB_cr2T040(string matrix, string tablename, MySQLConnection conn,Common MyCommon.Common)
        public static  TableField_T040 FindFromTB_cr2T040(string matrix, string tablename, MySqlConnection conn/*, Common MyCommon.Common*/)
        {
            int iFoundQty = 0;
            TableField_T040 res = new TableField_T040();
            string sql;
            DataTable dt = new DataTable();
            res.init();
            sql = string.Format("select partid, offload, type_id, familycode, obj31, obj36, obj45, obj50, obj69, obj70, obj71, obj72, obj73, obj74 from {0} where partid = {1} order by offload desc limit 1", tablename, matrix);
            dt = ShopfloorDB.Query(sql);
            /*DataTable dt = new MySQLSelectCommand(conn,
                new string[] { "partid", "offload", "type_id", "familycode", "obj31", "obj36", "obj45", "obj50", "obj69", "obj70", "obj71", "obj72", "obj73", "obj74" },
                new string[] { tablename },
                new object[,] { { "partid", "=", matrix } },
                null,
                new string[,] { { "offload", "desc limit 1" } }).Table;*/
            iFoundQty = dt.Rows.Count;

            if (dt.Rows.Count < 1) return res;
            try
            {
                res.partid_ = dt.Rows[0][0].ToString();
                res.offload_ = Convert.ToInt64(dt.Rows[0][1].ToString());
                res.type_id_ = Convert.ToInt32(dt.Rows[0][2].ToString());
                res.familycode_ = Convert.ToInt32(dt.Rows[0][3].ToString());
                res.obj31_PRO_OP43_MD_FM_FLOW = Convert.ToDouble(dt.Rows[0][4].ToString());
                res.obj36_PRO_OP43_MS_FM_FLOW = Convert.ToDouble(dt.Rows[0][5].ToString());
                res.obj45_PRO_OP44_MD_BAL_FLOW = Convert.ToDouble(dt.Rows[0][6].ToString());
                res.obj50_PRO_OP44_MS_BAL_FLOW = Convert.ToDouble(dt.Rows[0][7].ToString());
                res.obj69_PRO_OP44_G_MD_BAL_MULT = Convert.ToDouble(dt.Rows[0][8].ToString());
                res.obj70_PRO_OP44_G_MS_BAL_MULT = Convert.ToDouble(dt.Rows[0][9].ToString());
                res.obj71_PRO_OP43_G_MD_FM_MULT = Convert.ToDouble(dt.Rows[0][10].ToString());
                res.obj72_PRO_OP43_G_MS_FM_MULT = Convert.ToDouble(dt.Rows[0][11].ToString());
                res.obj73_PRO_OP44_G_MD_BAL_MULT = Convert.ToDouble(dt.Rows[0][12].ToString());
                res.obj74_PRO_OP44_G_MS_BAL_MULT = Convert.ToDouble(dt.Rows[0][13].ToString());
            }
            catch (FormatException frmE)
            {
                System.IO.StreamWriter sw = new StreamWriter(System.Windows.Forms.Application.StartupPath.TrimEnd('\\') + "\\TB100Functions.log");
                sw.WriteLine(frmE.Message);
                sw.Close();
            }
            dt.Dispose();
            dt = null;
            return res;
        }


        //public TableField_cr3line1  FindFromTB_cr3line1(string matrix, string tablename, MySQLConnection conn,Common MyCommon.Common,bool BalNotEmpty)
        public static  TableField_cr3line1 FindFromTB_cr3line1(string matrix, string tablename, MySqlConnection conn, /*Common MyCommon.Common, */bool BalNotEmpty)
        {
            int iFoundQty = 0;
            TableField_cr3line1 res = new TableField_cr3line1();
            string sql;
            DataTable dt = new DataTable();

            res.init();

            if (BalNotEmpty)
            {
                sql = string.Format("select partid, offload, type_id, familycode, obj31, obj36, obj45, obj50, obj69, obj70, obj71, obj72, obj73, obj74 from {0} where partid = {1} order by offload desc limit 1", tablename, matrix);
                /* dt = new MySQLSelectCommand(conn,
                     new string[] { "PartID", "Offload", "Type_ID", "FamilyCode", "`140430022`", "`140430030`", "`1404300210`", "`140430038`","`1404300112`" ,"`1404300113`"},
                     new string[] { tablename },
                     new object[,] { { "!isnull(`1404300210`) and !isnull(`140430038`) and " + "partid", "=", matrix } },
                     null,
                     new string[,] { { "offload", "desc limit 1" } }).Table;*/
            }
            else
            {
                sql = "XXXXXX";
                /* dt = new MySQLSelectCommand(conn,
                     new string[] { "PartID", "Offload", "Type_ID", "FamilyCode", "`140430022`", "`140430030`", "`1404300210`", "`140430038`", "`1404300112`", "`1404300113`" },
                     new string[] { tablename },
                     new object[,] { { "partid", "=", matrix } },
                     null,
                     new string[,] { { "offload", "desc limit 1" } }).Table;*/
            }
            dt = ShopfloorDB.Query(sql);
            iFoundQty = dt.Rows.Count;

            if (dt.Rows.Count < 1) return res;
            try
            {
                res.PartID_ = dt.Rows[0][0].ToString();                                             //0 *
                res.Offload_ = Convert.ToInt64(dt.Rows[0][1].ToString());                           //1 *
                res.Type_ID_ = Convert.ToInt32(dt.Rows[0][2].ToString());                           //2 *
                res.FamilyCode_ = Convert.ToInt32(dt.Rows[0][3].ToString());                        //3 *
                res.Obj_140430022_A_Qd_Flow = Convert.ToDouble(dt.Rows[0][4].ToString());         //4  Qd Flow
                res.Obj_140430030_A43_MS_FM_FLOW = Convert.ToDouble(dt.Rows[0][5].ToString());         //5 Qs Flow
                res.Obj_1404300210_A_Qd_Balance = Convert.ToDouble(dt.Rows[0][6].ToString());       //6 Qd Bal
                res.Obj_140430038_A43_MS_BAL_FLOW = Convert.ToDouble(dt.Rows[0][7].ToString());     //7 Qs Bal
                res.Obj_1404300112_A43_G_MD_BAL_MULT = Convert.ToDouble(dt.Rows[0][8].ToString());  //_A43_G_MD_BAL_MULT;
                res.Obj_1404300113_A43_G_MS_BAL_MULT = Convert.ToDouble(dt.Rows[0][9].ToString());//_A43_G_MS_BAL_MULT;


                //res.obj45_PRO_OP44_MD_BAL_FLOW = Convert.ToDouble(dt.Rows[0][6].ToString());        //6
                /* res.obj50_PRO_OP44_MS_BAL_FLOW = Convert.ToDouble(dt.Rows[0][7].ToString());        //7
                 res.obj69_PRO_OP44_G_MD_BAL_MULT = Convert.ToDouble(dt.Rows[0][8].ToString());      //8
                 res.obj70_PRO_OP44_G_MS_BAL_MULT = Convert.ToDouble(dt.Rows[0][9].ToString());      //9
                 res.obj71_PRO_OP43_G_MD_FM_MULT = Convert.ToDouble(dt.Rows[0][10].ToString());      //10
                 res.obj72_PRO_OP43_G_MS_FM_MULT = Convert.ToDouble(dt.Rows[0][11].ToString());      //11
                 res.obj73_PRO_OP44_G_MD_BAL_MULT = Convert.ToDouble(dt.Rows[0][12].ToString());     //12
                 res.obj74_PRO_OP44_G_MS_BAL_MULT = Convert.ToDouble(dt.Rows[0][13].ToString());     //13*/
            }
            catch (FormatException frmE)
            {
                System.IO.StreamWriter sw = new StreamWriter(System.Windows.Forms.Application.StartupPath.TrimEnd('\\') + "\\TB100Functions.log");
                sw.WriteLine(frmE.Message);
                sw.Close();
            }
            dt.Dispose();
            dt = null;
            return res;
        }


        //public  TableFields_corrNominal7 FindFromTB_corrNominal7(int type_id, long offloadTime, MySQLConnection conn)
        public static TableFields_corrNominal7 FindFromTB_corrNominal7(int type_id, long offloadTime, MySqlConnection conn)
        {
            int iFoundQty = 0;
            TableFields_corrNominal7 res = new TableFields_corrNominal7();
            string sql = "";
            res.init();
            /*DataTable dtNorminal = new MySQLSelectCommand(conn,
                                    new string[] { "qshighlimitperc", "qslowlimitperc", "product", "type_id", "dynamic", "static", "pressure", "uniqueID", "validFrom", "validTo" },
                //new string[] { myCR1T040.thisTableName },
                                    new string[] { "corrNominal7" },
                                    new object[,] { { "type_id", "=", type_id.ToString ()  }, { "validFrom", "<=", offloadTime .ToString () }, { "validTo", ">", offloadTime .ToString () } },
                                    null,
                                    new string[,] { { "validTo", "desc" } }).Table;
             */

            DataTable dtNorminal = new DataTable();
            dtNorminal = ShopfloorDB.Query(sql);
            iFoundQty = dtNorminal.Rows.Count;
            if (iFoundQty == 0) return res;
            res.qshighlimitperc = Convert.ToDouble(dtNorminal.Rows[0][0].ToString());
            res.qslowlimitperc = Convert.ToDouble(dtNorminal.Rows[0][1].ToString());
            res.product = Convert.ToInt32(dtNorminal.Rows[0][2].ToString());
            res.type_id = Convert.ToInt32(dtNorminal.Rows[0][3].ToString());
            res.dynamic = Convert.ToDouble(dtNorminal.Rows[0][4].ToString());
            res.Qstatic = Convert.ToDouble(dtNorminal.Rows[0][5].ToString());
            res.pressure = Convert.ToDouble(dtNorminal.Rows[0][6].ToString());
            res.uniqueID = Convert.ToInt32(dtNorminal.Rows[0][7].ToString());
            res.validFrom = Convert.ToInt64(dtNorminal.Rows[0][8].ToString());
            res.validTo = Convert.ToInt64(dtNorminal.Rows[0][9].ToString());
            dtNorminal.Dispose();
            dtNorminal = null;
            return res;

        }


        //public TableFields_cr1TB100 FindFromTB_TB100(string matrix, MySQLConnection conn,Common MyCommon.Common)
        public static TableFields_cr1TB100 FindFromTB_TB100(string matrix, MySqlConnection conn/*, Common MyCommon.Common*/)
        {
            int iFoundQty = 0;
            string sql = "";
            DataTable dt = new DataTable();
            TableFields_cr1TB100 res = new TableFields_cr1TB100();
            res.init();
            try
            {
                /*DataTable dt = new MySQLSelectCommand(conn,
                                        new string[] { "uniqueID", "partid", "offload", "type_id", "dynamic_mean", "static_mean", "dynamic_shift", "static_shift" },
                    //new string[] { myCR1T040.thisTableName },
                                        new string[] { res.thisTableName },
                                        new object[,] { { "partid", "=", matrix } },
                                        null,
                                        new string[,] { { "offload", "desc limit 1" } }).Table;*/
                sql = string.Format(@"select uniqueID, partid, offload, type_id,dynamic_mean,static_mean,dynamic_shift,static_shift from {0} where partid='{1}' order by offload desc limit 1",res .thisTableName ,matrix);
                dt = ShopfloorDB.Query(sql);
                iFoundQty = dt.Rows.Count;
                if (iFoundQty == 0) return res;
                res.uniqueID = Convert.ToInt64(dt.Rows[0][0].ToString());
                res.partid = dt.Rows[0][1].ToString();
                res.offload = Convert.ToInt64(dt.Rows[0][2].ToString());
                res.type_id = Convert.ToInt32(dt.Rows[0][3].ToString());
                res.dynamic_mean = Convert.ToDouble(dt.Rows[0][4].ToString());
                res.static_mean = Convert.ToDouble(dt.Rows[0][5].ToString());
                res.dynamic_shift = Convert.ToDouble(dt.Rows[0][6].ToString());
                res.static_shift = Convert.ToDouble(dt.Rows[0][7].ToString());
                dt.Dispose();
                dt = null;
            }
            catch (NullReferenceException e)
            {
                System.IO.StreamWriter sw = new StreamWriter(System.Windows.Forms.Application.StartupPath.TrimEnd('\\') + "\\TB100Functions.log");
                sw.WriteLine(e.Message);
                sw.Close();
                return res;
            }

            return res;

        }


    }

    public class TB100Result
    {
        public string Testplan;
        public setpoint QdNominal;
        public setpoint QsNominal;
        public setpoint TestPressure;
        public eDriverType DriverType;
        public Injector[] myInjectors = new Injector[6];

        public TB100Result()
        {
            int i;
            for (i = 0; i < myInjectors.Length; i++)
            {
                myInjectors[i] = new Injector();
            }
        }

        /// <summary>读取一个ttx文件的内容，并将其转换为一组喷油器的数据，保存在myInjectors数组里面
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public int SetTB100ResultFromFile(string fileName/*,Common MyCommon.Common*/)
        {
            int i = 0, iStart = 0, iEnd = 0;
            string sTemp;
            string[] sArr = new string[] { };
            System.IO.StreamReader myReader = new System.IO.StreamReader(fileName);

            //读出testplan
            try
            {
                while (!myReader.EndOfStream)
                {
                    sTemp = myReader.ReadLine();
                    if (sTemp.Contains("Plan Code"))//testplan行
                    {
                        iStart = sTemp.IndexOf('\t');
                        iEnd = sTemp.IndexOf("\t", iStart + 1);
                        Testplan = sTemp.Substring(iStart, iEnd - iStart).Replace('"', ' ').Trim();
                    }
                    if (sTemp.Contains("Injector Driver"))
                    {
                        if (sTemp.Contains("DPS")) DriverType = eDriverType.DPS;
                        if (sTemp.Contains("ATI")) DriverType = eDriverType.ATIC39;
                        if (sTemp.Contains("EEC")) DriverType = eDriverType.EEC_V;
                        if (sTemp.Contains("ATM")) DriverType = eDriverType.ATM_36;
                    }
                    if (sTemp.Contains("Test Pressure"))
                    {
                        iStart = sTemp.IndexOf('\t');
                        iEnd = sTemp.IndexOf('\t', iStart + 1);
                        TestPressure.Setpoint = Convert.ToDouble(sTemp.Substring(iStart, iEnd - iStart));
                        iStart = sTemp.IndexOf('\t', iEnd + 1);
                        TestPressure.Uplimit = Convert.ToDouble(sTemp.Substring(iStart));
                        TestPressure.Lowelimit = TestPressure.Uplimit;
                    }

                    if (sTemp.Contains("Serial Number"))
                    {
                        sArr = sTemp.Split('\t');
                        for (i = 0; i < 6; i++)
                        {
                            myInjectors[i].Matrix=(sArr[i + 1].Replace('"', ' ').Trim());
                            myInjectors[i].Testplan=(Testplan);
                        }
                    }
                    if (sTemp.Contains("Qdn ["))
                    {
                        QdNominal.Setpoint = Convert.ToDouble(sTemp.Substring(sTemp.IndexOf('\t')).Replace('"', ' ').Trim());
                    }
                    if (sTemp.Contains("Qd Mean"))
                    {
                        sArr = sTemp.Split('\t');
                        for (i = 0; i < 6; i++) myInjectors[i].Qd=(Convert.ToDouble(sArr[i + 1].Replace('"', ' ').Trim()));
                    }
                    if (sTemp.Contains("Shift from Qdn"))
                    {
                        sArr = sTemp.Split('\t');
                        for (i = 0; i < 6; i++) myInjectors[i].QdShift=(Convert.ToDouble(sArr[i + 1].Replace('"', ' ').Trim()));
                    }
                    if (sTemp.Contains("Qsn ["))
                    {
                        QsNominal.Setpoint = Convert.ToDouble(sTemp.Substring(sTemp.IndexOf('\t')).Replace('"', ' ').Trim()) / 10000;

                    }
                    if (sTemp.Contains("Qs Mean"))
                    {
                        sArr = sTemp.Split('\t');
                        for (i = 0; i < 6; i++) myInjectors[i].Qs=(Convert.ToDouble(sArr[i + 1].Replace('"', ' ').Trim()));
                    }
                    if (sTemp.Contains("Shift from Qsn"))
                    {
                        sArr = sTemp.Split('\t');
                        for (i = 0; i < 6; i++) myInjectors[i].QsShift=(Convert.ToDouble(sArr[i + 1].Replace('"', ' ').Trim()));
                    }
                }
            }

            catch (FormatException eFrm)
            {
                System.IO.StreamWriter sw = new StreamWriter(System.Windows.Forms.Application.StartupPath.TrimEnd('\\') + "\\TB100Functions.log");
                sw.WriteLine(eFrm.Message);
                sw.Close();
            }

            myReader.Close();
            return 0;
        }

        public string GetDriverType()
        {
            switch (DriverType)
            {
                case eDriverType.ATIC39: { return "ATIC39"; }
                case eDriverType.DPS: { return "DPS"; }
                case eDriverType.EEC_V: { return "EEC_V"; }
                case eDriverType.ATM_36: { return "ATM_36"; }
                default: return "Error";
            }
        }

        public void SetDriveType(eDriverType theDriveType)
        {
            DriverType = theDriveType;
        }

    }

    public class TB100Group
    {
        public string Testplan = "";
        ArrayList ArrInjectors = new ArrayList();
        public Injector[] Injectors = new Injector[] { };

        //ArrayList Groups = new TB100Group() ;

        public TB100Group(string testplan, Injector[] allInjectors)
        {
            int i;
            GroupCreate(testplan);
            foreach (Injector temp in allInjectors) AddInjector(temp);

            Injectors = new Injector[ArrInjectors.Count];
            i = 0;
            foreach (Injector temp in ArrInjectors)
                Injectors[i++] = temp;

        }
        public int GroupCreate(string TP)
        {
            if ((Testplan == "") && (TP.Replace('\0', ' ').Trim() != ""))
            {
                Testplan = TP;
                return 0;
            }
            else return -1;
        }
        public int AddInjector(Injector injectorInfo)
        {
            if ((injectorInfo.Testplan == Testplan) && (Testplan != ""))    //要添加的Testplan 和 当前testplan相同
            {
                if (!this.ArrInjectors.Contains(injectorInfo))//不包含当前要添加的喷油器信息,添加进组
                {
                    ArrInjectors.Add(injectorInfo);
                    return ArrInjectors.Count;
                }
                else
                {
                    return -1;//当前喷油器已经存在
                }
            }
            else
            {
                return -2;//当前Testplan 与喷油器testplan不符
            }
        }

        /// <summary> 获取这组喷油器都包含哪些Testplan号
        /// </summary>
        public ArrayList getInjectorsTPGroup(FixedInjectorGroup injectorGroupInfo)
        {
            ArrayList TP = new ArrayList();
            FixedInjectorGroup groupTemp = injectorGroupInfo;

            int i;

            TP.Add(groupTemp.AllInjectors[0].Testplan);//第一个Testplan号

            for (i = 0; i < groupTemp.AllInjectors.Length; i++)
            {
                if (!TP.Contains(groupTemp.AllInjectors[i].Testplan))
                {
                    TP.Add(groupTemp.AllInjectors[i].Testplan);
                }

            }
            return TP;
        }
        
    }
}
